pintobyte rngit
Node / public / precursor-lxmfchat.git / files / xous-core / services / root-keys / dev-helpers / reference.py
Displaying Raw • Download
xous-core/services/root-keys/dev-helpers/reference.py main (17e4bce8) Text, 7.47 KB
#!/usr/bin/python3
import argparse
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto.Random import get_random_bytes
import binascii
import logging
import sys
"""
Reverse the order of bits in a word that is bitwidth bits wide
"""
def bitflip(data_block, bitwidth=32):
if bitwidth == 0:
return data_block
bytewidth = bitwidth // 8
bitswapped = bytearray()
i = 0
while i < len(data_block):
data = int.from_bytes(data_block[i:i+bytewidth], byteorder='big', signed=False)
b = '{:0{width}b}'.format(data, width=bitwidth)
bitswapped.extend(int(b[::-1], 2).to_bytes(bytewidth, byteorder='big'))
i = i + bytewidth
return bytes(bitswapped)
# assumes a, b are the same length eh?
def xor_bytes(a, b):
i = 0
y = bytearray()
while i < len(a):
y.extend((a[i] ^ b[i]).to_bytes(1, byteorder='little'))
i = i + 1
return bytes(y)
def patcher(bit_in, patch):
bitstream = bit_in[64:-160]
if len(patch) > 0:
# find beginning of type2 area
position = 0
type = -1
command = 0
while type != 2:
command = int.from_bytes(bitflip(bitstream[position:position+4]), byteorder='big')
position = position + 4
if (command & 0xE0000000) == 0x20000000:
type = 1
elif (command & 0xE0000000) == 0x40000000:
type = 2
else:
type = -1
count = 0x3ffffff & command # not used, but handy to have around
ostream = bytearray(bitstream)
# position now sits at the top of the type2 region
# apply patches to each frame specified, ignoring the "none" values
for line in patch:
d = line[1]
for index in range(len(d)):
if d[index].strip() != 'none':
data = bitflip(int(d[index],16).to_bytes(4, 'big'))
frame_num = int(line[0],16)
for b in range(4):
stream_pos = position + frame_num * 101 * 4 + index * 4 + b
ostream[stream_pos] = data[b]
return bytes(ostream)
else:
return bitstream
def dumpframes(ofile, framestream):
position = 0
type = -1
command = 0
while type != 2:
command = int.from_bytes(framestream[position:position+4], byteorder='big')
position = position + 4
if (command & 0xE0000000) == 0x20000000:
type = 1
elif (command & 0xE0000000) == 0x40000000:
type = 2
else:
type = -1
count = 0x3ffffff & command
end = position + count
framecount = 0
while position < end:
ofile.write('0x{:08x},'.format(framecount))
framecount = framecount + 1
for i in range(101):
command = int.from_bytes(framestream[position:position + 4], byteorder='big')
position = position + 4
ofile.write(' 0x{:08x},'.format(command))
ofile.write('\\n')
def main():
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
#ifile = 'bbram1_soc_csr.bin'
ifile = '../../betrusted_soc_bbram.bin'
#with open('bbram-test1.nky', "r") as nky:
with open('dummy.nky', "r") as nky:
for lines in nky:
line = lines.split(' ')
if line[1] == '0':
nky_key = line[2].rstrip().rstrip(';')
if line[1] == 'StartCBC':
nky_iv = line[2].rstrip().rstrip(';')
if line[1] == 'HMAC':
nky_hmac = line[2].rstrip().rstrip(';')
logging.debug("original key: %s", nky_key)
logging.debug("original iv: %s", nky_iv)
logging.debug("original hmac: %s", nky_hmac)
key_bytes = int(nky_key, 16).to_bytes(32, byteorder='big')
# open the input file, and recover the plaintext
with open(ifile, "rb") as f:
binfile = f.read()
for i in range(64):
print(binascii.hexlify(binfile[i*4:((i+1)*4)]))
# search for structure
# 0x3001_6004 -> specifies the CBC key
# 4 words of CBC IV
# 0x3003_4001 -> ciphertext len
# 1 word of ciphertext len
# then ciphertext
position = 0
iv_pos = 0
while position < len(binfile):
cwd = int.from_bytes(binfile[position:position+4], 'big')
if cwd == 0x3001_6004:
iv_pos = position+4
if cwd == 0x3003_4001:
break
position = position + 1
position = position + 4
ciphertext_len = 4* int.from_bytes(binfile[position:position+4], 'big')
logging.debug("ciphertext len: %d", ciphertext_len)
position = position + 4
active_area = binfile[position : position+ciphertext_len]
logging.debug("start of ciphertext: %d", position)
iv_bytes = bitflip(binfile[iv_pos : iv_pos+0x10]) # note that the IV is embedded in the file
logging.debug("recovered iv: %s", binascii.hexlify(iv_bytes))
cipher = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
logging.debug("first: %s", binascii.hexlify(bitflip(active_area[:16])))
plain_bitstream = cipher.decrypt(bitflip(active_area))
logging.debug("first: %s", binascii.hexlify(plain_bitstream[:16]))
with open('plain.bin', 'wb') as plain_f:
plain_f.write(bitflip(plain_bitstream))
#for i in range(64):
# print(binascii.hexlify(bitflip(plain_bitstream[i*4:((i+1)*4)])))
#print(binascii.hexlify(bitflip(plain_bitstream)))
logging.debug("raw hmac: %s", binascii.hexlify(plain_bitstream[:64]))
hmac = xor_bytes(plain_bitstream[:32], plain_bitstream[32:64])
logging.debug("hmac: %s", binascii.hexlify(hmac))
logging.debug("plaintext len: %d", len(plain_bitstream))
logging.debug("initial plaintext: %s", binascii.hexlify(plain_bitstream[:256]))
h1 = SHA256.new()
k = 0
while k < len(plain_bitstream) - 320 - 160: # HMAC does /not/ cover the whole file, it stops 320 + 160 bytes short of the end
h1.update(bitflip(plain_bitstream[k:k+16], 32))
k = k + 16
h1_digest = h1.digest()
logging.debug("new digest1 : %s", binascii.hexlify(h1_digest))
logging.debug("new digest1 (in stored order): %s", binascii.hexlify(bitflip(h1_digest)))
footer = int(0x3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A).to_bytes(32, byteorder='big')
keyed_footer = xor_bytes(footer, hmac)
logging.debug("hmac (flipped): %s", binascii.hexlify(hmac))
logging.debug("masked_footer: %s", binascii.hexlify(keyed_footer))
h2 = SHA256.new()
h2.update(bitflip(keyed_footer))
h2.update(bitflip(footer))
#h2.update(keyed_footer)
#h2.update(footer)
h2.update(h1_digest)
h2_digest = h2.digest()
logging.debug("new digest2 : %s", binascii.hexlify(h2_digest))
logging.debug("new digest2 (in stored order): %s", binascii.hexlify(bitflip(h2_digest)))
logging.debug("ref digest: %s", binascii.hexlify(plain_bitstream[-32:]))
logging.debug("ref digest (flipped): %s", binascii.hexlify(bitflip(plain_bitstream[-32:])))
logging.debug("ref ending: %s", binascii.hexlify(plain_bitstream[-196:]))
if __name__ == "__main__":
main()
Served by rngit 1.4.0 - Generated in 0.03s